﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Strategy.Core.TradeStreams;
using Strategy.Core.TradeTypes;
using Strategy.Core.TradeStreams.Indicators;
using Strategy.Core.Trade;

namespace Strategy.Core.TradeStreams
{
    public class TradeIndicatorsStreamFactory : ITrader
    {
        protected TimeSpan timeInterval;
        protected List<ITradeIndicatorLevel> streams = new List<ITradeIndicatorLevel>();
        protected Dictionary<string, ITradeIndicatorLevel> dictionary = new Dictionary<string, ITradeIndicatorLevel>();
        protected virtual void addTradeStream(ITradeIndicatorLevel stream)
        {
            for (int j = 0; j < streams.Count; ++j)
            {
                if (stream.getLevel() <= streams[j].getLevel())
                {
                    streams.Insert(j, stream);
                    dictionary[stream.getID()] = stream;
                    return;
                }
            }
            streams.Add(stream);
            dictionary[stream.getID()] = stream;
        }
        public TradeIndicatorsStreamFactory(TimeSpan _timeInterval)
        {
            timeInterval = _timeInterval;
            addTradeStream(new CandleStream(_timeInterval));
        }
        public void Update(QuoteData qd)
        {
            foreach (var el in streams)
                el.Update(qd);
        }
        protected MACDIndicatorStream getMACD(int lp, int sp)
        {
            if (!dictionary.ContainsKey(MACDIndicatorStream.generateID(lp, sp)))
                addTradeStream(new MACDIndicatorStream(getEMA(sp), getEMA(lp)));
            return (MACDIndicatorStream)dictionary[MACDIndicatorStream.generateID(lp, sp)];
        }
        protected MACDSignalIndicatorStream getMACDSignal(int lp, int sp, int ap)
        {
            if (!dictionary.ContainsKey(MACDSignalIndicatorStream.generateID(lp, sp)))
                addTradeStream(new MACDSignalIndicatorStream(getEMA(sp), getEMA(lp),getEMA(ap)));
            return (MACDSignalIndicatorStream)dictionary[MACDSignalIndicatorStream.generateID(lp, sp,ap)];
        }
        protected RSIIndicatorStream getRSI(int period)
        {
            if (!dictionary.ContainsKey(RSIIndicatorStream.generateID(period)))
                addTradeStream(new RSIIndicatorStream(getCandleStream(), period));
            return (RSIIndicatorStream)dictionary[RSIIndicatorStream.generateID(period)];
        }
        protected EMAIndicatorStream getEMA(int period)
        {
            if (!dictionary.ContainsKey(EMAIndicatorStream.generateID(period)))
                addTradeStream(new EMAIndicatorStream(getCandleStream(), period));
            return (EMAIndicatorStream)dictionary[EMAIndicatorStream.generateID(period)];
        }
        private CandleStream getCandleStream()
        {
            return (CandleStream)dictionary[CandleStream.generateID()];
        }       
        public double macd(int lp, int sp) 
        {
            return getMACD(lp, sp).getByIndexFromEnd(0).Value;
        }
        public double macdSignal(int lp, int sp, int ap)
        {
            return getMACDSignal(lp, sp, ap).getByIndexFromEnd(0).Value;
        }
        public double ema(int period) 
        {
            return getEMA(period).getByIndexFromEnd(0).Value;
        }
        public Candle getCandle() { return getCandleStream().getByIndexFromEnd(0); }

        public double rsi(int period) { return getRSI(period).getByIndexFromEnd(0).Value; }

        public void init_macd(int lp, int sp)               { getMACD(lp, sp)          ; }
        public void init_macdSignal(int lp, int sp, int ap) { getMACDSignal(lp, sp, ap); }
        public void init_ema(int period)                    { getEMA(period)           ; }
        public void init_rsi(int period)                    { getRSI(period)           ; }


        #region ITrader Members

        public double value()
        {
            return getCandleStream().getByIndexFromEnd(0).Close;
        }

        #endregion
    }
}
